<!DOCTYPE html>

<html lang="zh-cn">

<head>
    <meta charset="utf-8">
    <title>ShaderMaterialTest</title>
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <style>
        html,
        body {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
    </style>
    <script src="../../assets/js/three.js"></script>
    <script src="../../assets/js/controls/OrbitControls.js"></script>
</head>

<body>
    <script>
        var scene = new THREE.Scene();

        var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 10000);
        camera.position.set(-2, 2, 2.5);

        var renderer = new THREE.WebGLRenderer({
            antialis: true
        });
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        var control = new THREE.OrbitControls(camera, renderer.domElement);

        scene.add(new THREE.PolarGridHelper());
        scene.add(new THREE.AxesHelper(5));

        var amLight = new THREE.AmbientLight(0xffffff, 0.4);
        scene.add(amLight);

        var dirLight = new THREE.DirectionalLight(0xffffff, 0.8);
        dirLight.position.set(100, 200, 300);
        scene.add(dirLight);
        scene.add(new THREE.DirectionalLightHelper(dirLight));

        var render = function () {
            requestAnimationFrame(render);
            renderer.render(scene, camera);
        };

        var fetchShader = function (url) {
            return new Promise(resolve => {
                fetch(url).then(response => {
                    if (response.ok) {
                        response.text().then(text => {
                            resolve(text);
                        });
                    }
                });
            });
        }

        var promise1 = fetchShader('shader/simple_vertex.glsl');
        var promise2 = fetchShader('shader/simple_frag.glsl');

        Promise.all([promise1, promise2]).then(result => {
            var geometry = new THREE.BoxBufferGeometry(1, 1, 1);

            var material = new THREE.RawShaderMaterial({
                flatShading: true,
                uniforms: {
                    color: {
                        type: 'v3',
                        value: new THREE.Vector3(1.0, 1.0, 0.0),
                    },
                    ambientColor: {
                        type: 'v3',
                        value: new THREE.Vector3().set(
                            amLight.color.r,
                            amLight.color.g,
                            amLight.color.b
                        ).multiplyScalar(amLight.intensity)
                    },
                    lightPosition: {
                        type: 'v3',
                        value: dirLight.position
                    },
                    diffuseColor: {
                        type: 'v3',
                        value: new THREE.Vector3(1.0, 1.0, 1.0)
                    },
                    shininess: {
                        type: 'f',
                        value: 30
                    }
                },
                vertexShader: result[0],
                fragmentShader: result[1],
            });

            var mesh = new THREE.Mesh(geometry, material);
            scene.add(mesh);
            render();
        });
    </script>
</body>

</html>